home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / rsynth / src / sgiplay.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  10.4 KB  |  450 lines

  1. #include <stdio.h>
  2. #include "audio.h"
  3.  
  4.  
  5. #define SAMP_RATE 8000
  6. long samp_rate = SAMP_RATE;
  7.  
  8. static ALport   Gaudio_port;
  9.  
  10. int audio_play(n, data)
  11.     int   n;
  12.     short *data;
  13. {
  14.     fprintf(stderr,"Audio Play %d Samples\n", n);
  15.     ALwritesamps(Gaudio_port, data, n);
  16.  
  17.     return(0);
  18. }
  19. int audio_init(argc, argv)
  20.     int argc;
  21.     char *argv[];
  22. {
  23.     ALconfig audio_port_config;
  24.     long     pvbuf[2];
  25.     long     buflen;
  26.  
  27.     pvbuf[0] = AL_OUTPUT_RATE;
  28.     pvbuf[1] = 8000;
  29.     buflen   = 2;
  30.     ALsetparams(AL_DEFAULT_DEVICE, pvbuf, buflen);
  31.  
  32.     audio_port_config = ALnewconfig();
  33.  
  34.     ALsetwidth(audio_port_config, 2);
  35.     ALsetchannels(audio_port_config, 1);
  36.    /*
  37.     *  Set a 1K internal buffer
  38.     *
  39.     */
  40.     ALsetqueuesize(audio_port_config, 1024);
  41.  
  42.     Gaudio_port = ALopenport("Say", "w", audio_port_config);
  43.  
  44.  
  45.  
  46.  
  47.     fprintf(stderr,"Audio Init\n");
  48.  
  49.     return(0);
  50. }
  51. void audio_term()
  52. {
  53.     fprintf(stderr,"Audio Term\n");
  54.  
  55.     while(ALgetfilled(Gaudio_port) > 0)sginap(1);
  56.     ALcloseport(Gaudio_port);
  57.  
  58. }
  59.  
  60.  
  61.  
  62. #ifdef SUN
  63.  
  64.  
  65. /*****************************************************************/
  66. /*****************************************************************/
  67. /***                                                           ***/
  68. /***                                                           ***/
  69. /***    Play out a 20kHz file on the SPARC                     ***/
  70. /***                                                           ***/
  71. /***                                                           ***/
  72. /***                H.F. Silverman 1/4/91                      ***/
  73. /***    Modified:   H.F. Silverman 1/16/91 for amax parameter  ***/
  74. /***    Modified:   A. Smith 2/14/91 for 8kHz for klatt synth  ***/
  75. /***                                                           ***/
  76. /*** Called: hplay(n,volume,amax,a)                            ***/
  77. /***                                                           ***/
  78. /***   int       n      -- No. of 8kHz pts.                    ***/
  79. /***   int    device    -- 0 -> speaker, 1 -> Jack             ***/
  80. /***                                                           ***/
  81. /***                                                           ***/
  82. /*****************************************************************/
  83. /*****************************************************************/
  84.  
  85. #include <stdio.h>
  86. #include <stdlib.h>
  87. #include <math.h>
  88. #include <errno.h>
  89. #include <ctype.h>
  90.  
  91. #include <unistd.h>
  92. #include <fcntl.h>
  93. #include <sys/types.h>
  94. #include <sys/file.h>
  95. #include <sys/filio.h>
  96. #include <sys/stat.h>
  97. #include <sys/param.h>
  98. #include <sys/signal.h>
  99.  
  100. #include <stropts.h>
  101. #include <sys/ioctl.h>
  102.  
  103. #include <multimedia/libaudio.h>
  104. #include <multimedia/audio_device.h>
  105. #include <multimedia/ulaw2linear.h>
  106. #include "proto.h"
  107. #include "getargs.h"
  108. #include "hplay.h"
  109.  
  110. #define SAMP_RATE 8000
  111. long samp_rate = SAMP_RATE;
  112.  
  113. /* Audio Parameters */
  114.  
  115. int Verbose = FALSE;
  116.                                 /* verbose messages */
  117. int Immediate = FALSE;
  118.                                 /* Should we hang waiting for device ? */
  119.  
  120. static int async = TRUE;
  121.  
  122. static Audio_hdr dev_header;
  123.                                 /* audio header for device */
  124. static int dev_fd = -1;
  125.                                 /* file descriptor for audio device */
  126. char *dev_file = "/dev/audio";
  127.  
  128. static Audio_hdr ulaw_header;
  129.                                 /* audio header for file */
  130. static int ulaw_fd = -1;
  131.                                 /* file descriptor for .au ulaw file */
  132. static char *ulaw_file = NULL;
  133.  
  134. static int linear_fd = -1;
  135.  
  136. static int dev_kind = AUDIO_DEV_AMD;
  137.                                 /* file descriptor for 16 bit linear file */
  138. static char *linear_file = NULL;
  139.  
  140. char *prog = "hplay";
  141. char *Ifile;        /* current filename */
  142.  
  143. static void audio_catch
  144. PROTO((void))
  145. {
  146.  fprintf(stderr, "signal\n");
  147. }
  148.  
  149. static int audio_open
  150. PROTO((void))
  151. {
  152.  /* Try it quickly, first */
  153.  dev_fd = open(dev_file, O_WRONLY | O_NDELAY);
  154.  if ((dev_fd < 0) && (errno == EBUSY))
  155.   {
  156.    if (Immediate)
  157.     {
  158.      fprintf(stderr, "%s: %s is busy\n", prog, dev_file);
  159.      return 0;
  160.     }
  161.    if (Verbose)
  162.     {
  163.      fprintf(stderr, "%s: waiting for %s...", prog, dev_file);
  164.      (void) fflush(stderr);
  165.     }
  166.  
  167.    /* Now hang until it's open */
  168.  
  169.    dev_fd = open(dev_file, O_WRONLY);
  170.    if (Verbose)
  171.     fprintf(stderr, "%s\n", (dev_fd < 0) ? "" : "open");
  172.   }
  173.  if (dev_fd < 0)
  174.   {
  175.    fprintf(stderr, "%s: error opening ", prog);
  176.    perror(dev_file);
  177.    return 0;
  178.   }
  179.  else
  180.   {
  181.    /* Get the device output encoding configuration */
  182.    if (ioctl(dev_fd,AUDIO_GETDEV,&dev_kind))
  183.     {
  184.      /* Old releases of SunOs don't support the ioctl,
  185.         but can only be run on old machines which have AMD device...
  186.      */
  187.      dev_kind = AUDIO_DEV_AMD;
  188.     }
  189.    if (audio_get_play_config(dev_fd, &dev_header) != AUDIO_SUCCESS)
  190.     {
  191.      fprintf(stderr, "%s: %s is not an audio device\n", prog, dev_file);
  192.      close(dev_fd);
  193.      dev_fd = -1;
  194.      return 0;
  195.     }
  196.   }
  197.  return 1;
  198. }
  199.  
  200. int
  201. audio_init(argc, argv)
  202. int argc;
  203. char *argv[];
  204. {
  205.  int rate_set = 0;
  206.  int use_linear = 0;
  207.  int use_audio = 1;
  208.  double gain = -1.0;
  209.  int headphone = 2;
  210.  int speaker   = 2;
  211.  
  212.  prog = argv[0];
  213.  
  214.  argc = getargs(argc,argv,
  215.                 "g", "%lg", &gain,
  216.                 "r", "%d",  &rate_set,
  217.                 "h", NULL,  &headphone,
  218.                 "s", NULL,  &speaker,
  219.                 "a", NULL,  &use_audio,
  220.                 "L", NULL,  &use_linear,
  221.                 "u", "",    &ulaw_file,
  222.                 "l", "",    &linear_file,
  223.                 NULL);
  224.  
  225.  if (ulaw_file)
  226.   {
  227.    ulaw_fd = open(ulaw_file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
  228.    if (ulaw_fd < 0)
  229.     perror(ulaw_file);
  230.   }
  231.  
  232.  if (linear_file)
  233.   {
  234.    linear_fd = open(linear_file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
  235.    if (linear_fd < 0)
  236.     perror(linear_file);
  237.   }
  238.  
  239.  if (rate_set)
  240.   {
  241.    samp_rate = rate_set;
  242.   }
  243.  
  244.  if (use_audio && audio_open())
  245.   {
  246.    if (!rate_set)
  247.     samp_rate = dev_header.sample_rate;
  248.  
  249.    if (rate_set || use_linear)
  250.     {
  251.      dev_header.sample_rate = samp_rate;
  252.      if (samp_rate > 8000 || use_linear)
  253.       {
  254.        dev_header.encoding = AUDIO_ENCODING_LINEAR;
  255.        dev_header.bytes_per_unit = 2;
  256.       }
  257.      if (audio_set_play_config(dev_fd, &dev_header) != AUDIO_SUCCESS)
  258.       {
  259.        fprintf(stderr, "%s : %s cannot accept sample rate of %dHz\n",
  260.                prog, dev_file, samp_rate);
  261.        close(dev_fd);
  262.        dev_fd = -1;
  263.       }
  264.     }
  265.   }
  266.  if (dev_fd >= 0)
  267.   {int myport = 0;
  268.    if (gain >= 0.0)
  269.     {
  270.      int err = audio_set_play_gain(dev_fd, &gain);
  271.      if (err != AUDIO_SUCCESS)
  272.       {
  273.        fprintf(stderr, "%s: could not set output volume for %s\n", prog, dev_file);
  274.       }
  275.     }
  276.  
  277.    if (headphone != 2)
  278.     {
  279.      if (headphone)
  280.       myport |= AUDIO_HEADPHONE;
  281.      else
  282.       myport &= ~AUDIO_HEADPHONE;
  283.     }
  284.  
  285.    if (speaker != 2)
  286.     {
  287.      if (speaker)
  288.       myport |= AUDIO_SPEAKER;
  289.      else
  290.       myport &= ~AUDIO_SPEAKER;
  291.     }
  292.  
  293.    if (myport != 0)
  294.     audio_set_play_port(dev_fd, &myport);
  295.  
  296.    if (async)
  297.     {
  298.      int flag = 1;
  299.      /* May need to use streams calls to send a SIGPOLL when write
  300.         buffer is no longer full and use non-blocking writes, and
  301.         manipluate our own buffer of unwritten data.
  302.  
  303.         However, at present just use FIOASYNC which means write
  304.         returns as soon as it can queue the data (I think).
  305.      */
  306.      signal(SIGIO, audio_catch);
  307.      ioctl(dev_fd, FIOASYNC, &flag);
  308.     }
  309.   }
  310.  if (ulaw_fd >= 0)
  311.   {
  312.    ulaw_header.sample_rate = samp_rate;
  313.    if (samp_rate > 8000)
  314.     {
  315.      ulaw_header.encoding = AUDIO_ENCODING_LINEAR;
  316.      ulaw_header.bytes_per_unit = 2;
  317.     }
  318.    else
  319.     {
  320.      ulaw_header.encoding = AUDIO_ENCODING_ULAW;
  321.      ulaw_header.bytes_per_unit = 1;
  322.     }
  323.    ulaw_header.samples_per_unit = 1;
  324.    ulaw_header.channels = 1;
  325.    ulaw_header.data_size = 0;
  326.  
  327.    /* Write header - note that data_size is unknown at this stage,
  328.       if all goes well we will lseek back and do this again
  329.       in audio_term()
  330.    */
  331.    audio_write_filehdr(ulaw_fd, &ulaw_header, NULL, 0);
  332.   }
  333.  return argc;
  334. }
  335.  
  336. void
  337. audio_term()
  338. {
  339.  /* Close audio system  */
  340.  if (dev_fd >= 0)
  341.   {
  342.    audio_drain(dev_fd, FALSE);
  343.    close(dev_fd);
  344.    dev_fd = -1;
  345.    if (async)
  346.     signal(SIGPOLL, SIG_DFL);
  347.   }
  348.  
  349.  /* Finish ulaw file */
  350.  if (ulaw_fd >= 0)
  351.   {
  352.    off_t here = lseek(ulaw_fd, 0L, SEEK_CUR);
  353.    if (here >= 0)
  354.     {
  355.      /* can seek this file - truncate it */
  356.      ftruncate(ulaw_fd, here);
  357.  
  358.      /* Now go back and overwite header with actual size */
  359.      if (lseek(ulaw_fd, 0L, SEEK_SET) == 0)
  360.       {
  361.        audio_write_filehdr(ulaw_fd, &ulaw_header, NULL, 0);
  362.       }
  363.     }
  364.    close(ulaw_fd);
  365.    ulaw_fd = -1;
  366.   }
  367.  
  368.  /* Finish linear file */
  369.  if (linear_fd >= 0)
  370.   {
  371.    ftruncate(linear_fd, lseek(linear_fd, 0L, SEEK_CUR));
  372.    close(linear_fd);
  373.    linear_fd = -1;
  374.   }
  375. }
  376.  
  377. void
  378. audio_play(n, data)
  379. int n;
  380. short *data;
  381. {
  382.  if (n > 0)
  383.   {
  384.    if (linear_fd >= 0)
  385.     {
  386.      unsigned size = n * sizeof(short);
  387.      if (write(linear_fd, data, n * sizeof(short)) != size)
  388.             perror("write");
  389.     }
  390.  
  391.    if (dev_fd >= 0 && dev_header.encoding == AUDIO_ENCODING_LINEAR)
  392.     {
  393.      unsigned size = n * sizeof(short);
  394.      if (write(dev_fd, data, n * sizeof(short)) != size)
  395.             perror("write");
  396.     }
  397.  
  398.    if (ulaw_fd >= 0 && ulaw_header.encoding == AUDIO_ENCODING_LINEAR)
  399.     {
  400.      unsigned size = n * sizeof(short);
  401.      if (write(ulaw_fd, data, n * sizeof(short)) != size)
  402.             perror("write");
  403.      else
  404.       ulaw_header.data_size += size;
  405.     }
  406.  
  407.    if ((dev_fd  >= 0 && dev_header.encoding == AUDIO_ENCODING_ULAW) ||
  408.        (ulaw_fd >= 0 && ulaw_header.encoding == AUDIO_ENCODING_ULAW))
  409.     {
  410.      unsigned char *plabuf = (unsigned char *) malloc(n);
  411.      if (plabuf)
  412.       {
  413.        int w;
  414.        unsigned char *p = plabuf;
  415.        unsigned char *e = p + n;
  416.        while (p < e)
  417.         {
  418.          *p++ = audio_s2u(*data++);
  419.         }
  420.        if (dev_fd >= 0 && dev_header.encoding == AUDIO_ENCODING_ULAW)
  421.         {
  422.          if ((w = write(dev_fd, plabuf, n)) != n)
  423.           {
  424.            if (w == -1)
  425.             perror("audio");
  426.            else
  427.             {
  428.              fprintf(stderr, "Writing %u, only wrote %u\n", n, w);
  429.             }
  430.            abort();
  431.           }
  432.         }
  433.        if (ulaw_fd >= 0 && ulaw_header.encoding == AUDIO_ENCODING_ULAW)
  434.         {
  435.          if (write(ulaw_fd, plabuf, n) != n)
  436.           perror(ulaw_file);
  437.          else
  438.           ulaw_header.data_size += n;
  439.         }
  440.        free(plabuf);
  441.       }
  442.      else
  443.       {
  444.        fprintf(stderr, "%s : No memory for ulaw data\n", prog);
  445.       }
  446.     }
  447.   }
  448. }
  449. #endif
  450.